/**
 * API 客户端
 * 统一的 HTTP 请求封装
 */

import { getAccessToken, refreshToken, logout } from './auth';

const API_BASE = import.meta.env.VITE_API_BASE_URL || 'http://localhost:5001/api';

interface RequestOptions extends RequestInit {
  skipAuth?: boolean;
}

// 添加刷新锁，防止并发刷新
let isRefreshing = false;
let refreshSubscribers: ((token: string) => void)[] = [];

function subscribeTokenRefresh(callback: (token: string) => void) {
  refreshSubscribers.push(callback);
}

function onTokenRefreshed(token: string) {
  refreshSubscribers.forEach(callback => callback(token));
  refreshSubscribers = [];
}

/**
 * 统一的请求方法
 */
async function request<T>(
  endpoint: string,
  options: RequestOptions = {}
): Promise<T> {
  const { skipAuth = false, ...fetchOptions } = options;

  const headers: Record<string, string> = {
    'Content-Type': 'application/json',
    ...(fetchOptions.headers as Record<string, string>),
  };

  // 添加认证 token
  if (!skipAuth) {
    const token = getAccessToken();
    if (token) {
      headers['Authorization'] = `Bearer ${token}`;
    }
  }

  let response = await fetch(`${API_BASE}${endpoint}`, {
    ...fetchOptions,
    headers,
  });

  // 如果 token 过期，尝试刷新
  if (response.status === 401 && !skipAuth) {
    if (!isRefreshing) {
      isRefreshing = true;
      
      try {
        const refreshed = await refreshToken();
        
        if (refreshed) {
          const newToken = getAccessToken();
          if (newToken) {
            onTokenRefreshed(newToken);
            isRefreshing = false;
            
            // 重试请求
            headers['Authorization'] = `Bearer ${newToken}`;
            response = await fetch(`${API_BASE}${endpoint}`, {
              ...fetchOptions,
              headers,
            });
          }
        } else {
          // 刷新失败，清除认证状态并跳转到登录页
          isRefreshing = false;
          await logout();
          window.location.href = '/login';
          throw new Error('Authentication failed. Please login again.');
        }
      } catch (error) {
        isRefreshing = false;
        await logout();
        window.location.href = '/login';
        throw error;
      }
    } else {
      // 等待刷新完成
      const newToken = await new Promise<string>((resolve) => {
        subscribeTokenRefresh((token: string) => {
          resolve(token);
        });
      });
      
      // 用新 token 重试
      headers['Authorization'] = `Bearer ${newToken}`;
      response = await fetch(`${API_BASE}${endpoint}`, {
        ...fetchOptions,
        headers,
      });
    }
  }

  if (!response.ok) {
    const error = await response.json().catch(() => ({
      error: 'Request failed',
    }));
    throw new Error(error.error || `Request failed with status ${response.status}`);
  }

  return response.json();
}

/**
 * GET 请求
 */
export async function get<T>(endpoint: string, options?: RequestOptions): Promise<T> {
  return request<T>(endpoint, { ...options, method: 'GET' });
}

/**
 * POST 请求
 */
export async function post<T>(
  endpoint: string,
  data?: unknown,
  options?: RequestOptions
): Promise<T> {
  return request<T>(endpoint, {
    ...options,
    method: 'POST',
    body: data ? JSON.stringify(data) : undefined,
  });
}

/**
 * PUT 请求
 */
export async function put<T>(
  endpoint: string,
  data?: unknown,
  options?: RequestOptions
): Promise<T> {
  return request<T>(endpoint, {
    ...options,
    method: 'PUT',
    body: data ? JSON.stringify(data) : undefined,
  });
}

/**
 * DELETE 请求
 */
export async function del<T>(endpoint: string, options?: RequestOptions): Promise<T> {
  return request<T>(endpoint, { ...options, method: 'DELETE' });
}

// ============ API 方法 ============

// Todos API
export interface Todo {
  id: number;
  text: string;
  completed: boolean;
  created_at: string;
  updated_at: string;
}

export const todosAPI = {
  getAll: (params?: { page?: number; per_page?: number; q?: string; completed?: boolean; sort?: 'created_at' | '-created_at' }) => {
    const search = new URLSearchParams();
    if (params?.page) search.set('page', String(params.page));
    if (params?.per_page) search.set('per_page', String(params.per_page));
    if (params?.q) search.set('q', params.q);
    if (typeof params?.completed === 'boolean') search.set('completed', params.completed ? 'true' : 'false');
    if (params?.sort) search.set('sort', params.sort);
    const qs = search.toString();
    const url = `/todos${qs ? `?${qs}` : ''}`;
    return get<{ todos: Todo[]; pagination?: unknown }>(url);
  },
  create: (text: string) => post<{ success: boolean; todo: Todo }>('/todos', { text }),
  update: (id: number, data: Partial<Pick<Todo, 'text' | 'completed'>>) =>
    put<{ success: boolean; todo: Todo }>(`/todos/${id}`, data),
  delete: (id: number) => del<{ success: boolean; message: string }>(`/todos/${id}`),
};

// Agents API
export interface Agent {
  id: string;
  name: string;
  url: string;
  description?: string;
  icon?: string;
  createdAt: string;
  updatedAt: string;
}

export const agentsAPI = {
  getAll: () => get<{ agents: Agent[] }>('/agents'),
  getById: (id: string) => get<{ agent: Agent }>(`/agents/${id}`),
  create: (data: Omit<Agent, 'id' | 'createdAt' | 'updatedAt'>) =>
    post<{ success: boolean; agent: Agent }>('/agents', data),
  update: (id: string, data: Partial<Omit<Agent, 'id' | 'createdAt' | 'updatedAt'>>) =>
    put<{ success: boolean; agent: Agent }>(`/agents/${id}`, data),
  delete: (id: string) => del<{ success: boolean; message: string }>(`/agents/${id}`),
};

// Notes API
export interface Note {
  id: number;
  title: string;
  content: string;
  created_at: string;
  updated_at: string;
}

export const notesAPI = {
  getAll: () => get<{ notes: Note[] }>('/notes'),
  getById: (id: number) => get<{ note: Note }>(`/notes/${id}`),
  create: (data: Pick<Note, 'title' | 'content'>) =>
    post<{ success: boolean; note: Note }>('/notes', data),
  update: (id: number, data: Partial<Pick<Note, 'title' | 'content'>>) =>
    put<{ success: boolean; note: Note }>(`/notes/${id}`, data),
  delete: (id: number) => del<{ success: boolean; message: string }>(`/notes/${id}`),
};

// Email Account API
export interface EmailAccount {
  id: string;
  name: string;
  email: string;
  smtp_server: string;
  smtp_port: number;
  imap_server: string;
  imap_port: number;
  username: string;
  use_ssl: boolean;
  is_default: boolean;
  description?: string;
  last_fetch_at?: string;
  is_fetching: boolean;
  last_sync_uid?: number;
  is_first_fetch: boolean;
  created_at: string;
  updated_at: string;
}

// Email Folder Interface
export interface EmailFolder {
  name: string;
  normalized_name: string;
  imap_name: string;
  email_count: number;
  is_system: boolean;
}

export const emailAccountsAPI = {
  getAll: () => get<{ accounts: EmailAccount[] }>('/email-accounts'),
  getById: (id: string) => get<{ account: EmailAccount }>(`/email-accounts/${id}`),
  create: (data: Omit<EmailAccount, 'id' | 'created_at' | 'updated_at'> & { password: string }) =>
    post<{ success: boolean; account: EmailAccount }>('/email-accounts', data),
  update: (id: string, data: Partial<Omit<EmailAccount, 'id' | 'created_at' | 'updated_at'> & { password?: string }>) =>
    put<{ success: boolean; account: EmailAccount }>(`/email-accounts/${id}`, data),
  delete: (id: string) => del<{ success: boolean; message: string }>(`/email-accounts/${id}`),
  sendTest: (id: string) => post<{ success: boolean; message: string }>(`/email-accounts/${id}/test`),
  fetchMessages: (id: string) => post<{ success: boolean; message: string; fetched_count?: number; is_fetching?: boolean }>(`/email-accounts/${id}/fetch`),
  getFetchStatus: (id: string) => get<{ is_fetching: boolean; last_fetch_at?: string; last_sync_uid?: number }>(`/email-accounts/${id}/fetch-status`),
  getStats: (id: string) => get<{
    success: boolean;
    account_id: string;
    account_email: string;
    db_message_count: number;
    total_message_count: number;
    folder_stats: Record<string, number>;
    is_first_fetch: boolean;
    last_fetch_at?: string;
    is_fetching: boolean;
  }>(`/email-accounts/${id}/stats`),
  clearMessages: (id: string) => post<{ success: boolean; message: string; deleted_count: number }>(`/email-accounts/${id}/clear`),
  getFolders: (id: string) => get<{ folders: EmailFolder[]; folder_map: Record<string, string> }>(`/email-accounts/${id}/folders`),
};

// Email Message API
export interface EmailMessage {
  id: number;
  email_account_id: string;
  message_id: string;
  imap_uid?: number;
  subject?: string;
  sender?: string;
  recipients: string[];
  cc: string[];
  body_text?: string;
  body_html?: string;
  attachments: any[];
  is_read: boolean;
  is_starred: boolean;
  is_full_content: boolean;
  content_size?: number;
  folder: string;
  received_at?: string;
  ai_summary?: string;
  created_at: string;
  updated_at: string;
}

export const emailMessagesAPI = {
  getAll: (params?: { 
    folder?: string; 
    is_read?: boolean; 
    account_id?: string; 
    search?: string; 
    page?: number; 
    per_page?: number 
  }) => {
    const search = new URLSearchParams();
    if (params?.folder) search.set('folder', params.folder);
    if (typeof params?.is_read === 'boolean') search.set('is_read', params.is_read ? 'true' : 'false');
    if (params?.account_id) search.set('account_id', params.account_id);
    if (params?.search) search.set('search', params.search);
    if (params?.page) search.set('page', String(params.page));
    if (params?.per_page) search.set('per_page', String(params.per_page));
    const qs = search.toString();
    const url = `/email-messages${qs ? `?${qs}` : ''}`;
    return get<{ messages: EmailMessage[]; pagination?: any }>(url);
  },
  getById: (id: number) => get<{ message: EmailMessage }>(`/email-messages/${id}`),
  update: (id: number, data: Partial<Pick<EmailMessage, 'is_read' | 'is_starred' | 'folder' | 'ai_summary'>>) =>
    put<{ success: boolean; message: EmailMessage }>(`/email-messages/${id}`, data),
  delete: (id: number) => del<{ success: boolean; message: string }>(`/email-messages/${id}`),
  send: async (data: { account_id: string; to: string; cc?: string; bcc?: string; subject: string; body: string; body_html?: string; attachments?: File[] }) => {
    // 如果有附件，使用 FormData
    if (data.attachments && data.attachments.length > 0) {
      const formData = new FormData();
      formData.append('account_id', data.account_id);
      formData.append('to', data.to);
      if (data.cc) formData.append('cc', data.cc);
      if (data.bcc) formData.append('bcc', data.bcc);
      formData.append('subject', data.subject);
      formData.append('body', data.body);
      if (data.body_html) formData.append('body_html', data.body_html);
      
      // 添加附件
      data.attachments.forEach(file => {
        formData.append('attachments', file);
      });
      
      // 使用特殊的请求方法处理 FormData
      const token = getAccessToken();
      const headers: Record<string, string> = {};
      if (token) {
        headers['Authorization'] = `Bearer ${token}`;
      }
      // 不设置 Content-Type，让浏览器自动设置（包含 boundary）
      
      const response = await fetch(`${API_BASE}/email-messages/send`, {
        method: 'POST',
        headers,
        body: formData,
      });
      
      if (!response.ok) {
        const error = await response.json().catch(() => ({ error: 'Request failed' }));
        throw new Error(error.error || `Request failed with status ${response.status}`);
      }
      
      return response.json();
    } else {
      // 没有附件，使用 JSON
      return post<{ success: boolean; message: string; message_id?: string; saved_to_db?: boolean }>('/email-messages/send', data);
    }
  },
  batchUpdate: (data: { message_ids: number[]; action: string }) =>
    post<{ success: boolean; message: string }>('/email-messages/batch', data),
  
  // 新增的IMAP优化API
  loadBody: (messageId: number) => 
    post<{ success: boolean; message: EmailMessage }>(`/email-messages/${messageId}/load-body`),
  
  loadMoreHistory: (params: {
    account_id: string;
    folder: string;
    before_uid?: number;
  }) => post<{ 
    success: boolean; 
    messages: EmailMessage[]; 
    has_more: boolean; 
    count: number 
  }>('/email-messages/load-more-history', params),
};

// AI提示词配置接口
export interface AIPromptConfig {
  id: number;
  user_id: number;
  module: string;
  prompt_template: string;
  is_active: boolean;
  created_at: string;
  updated_at: string;
}

export const aiPromptsAPI = {
  getAll: () => get<{ success: boolean; prompts: AIPromptConfig[] }>('/ai-prompts'),
  getByModule: (module: string) => get<{ success: boolean; prompt: AIPromptConfig }>(`/ai-prompts/${module}`),
  create: (data: Partial<AIPromptConfig>) => post<{ success: boolean; prompt: AIPromptConfig; message: string }>('/ai-prompts', data),
  update: (id: number, data: Partial<AIPromptConfig>) => put<{ success: boolean; prompt: AIPromptConfig; message: string }>(`/ai-prompts/${id}`, data),
  updateByModule: (module: string, data: Partial<AIPromptConfig>) => put<{ success: boolean; prompt: AIPromptConfig; message: string }>(`/ai-prompts/${module}`, data),
  delete: (id: number) => del<{ success: boolean; message: string }>(`/ai-prompts/${id}`),
  resetToDefault: (module: string) => post<{ success: boolean; prompt: AIPromptConfig; message: string }>(`/ai-prompts/${module}/reset`),
};

